/**
 * 将表结构转换为CodeMirror的格式 V:20220413
 */

/* 输入格式： tableInfo = {
	"tableNameDesc": "活动信息表",
	"tableName": "DwActivityCinemaInfo",
	"databaseDesc": null,
	"database": null,
	"fieldList": [{
		"fieldName": "id",
		"fieldNameDesc": "主键id",
		"fieldType": "java.lang.Integer",
		"hasNull": false,
		"source": "",
		"desc": null,
		"allowValue": "值域描述"
	}]}
	输出格式： {dw_activity_cinema_info: ["id#主键id 值域描述", "score#字段score", "birthDate#字段birthDate"]}
	*/
function getHintTableInfo(data) {
	 var tables = {" ":{}};
	 if (!data || !data.result || !data.rows || data.rows.length == 0) {
		 return tables;
	 }
	 var rows = data.rows;
	 rows.sort(function(x, y) {return x.tableName > y.tableName ? 1 : x.tableName == y.tableName ? 0 : -1});
   	 for (var i = 0; i < rows.length; i++){
   		 var tableInfo = rows[i];
   		 if (tableInfo.tableName) {
   		 	var tableName = tableInfo.tableName;
   		 	var fieldList = [];
   		 	if (tableInfo.fieldList){
   		 		for (var j = 0; j < tableInfo.fieldList.length; j++){
   		 			var fieldInfo = tableInfo.fieldList[j];
   		 			if (fieldInfo){
   		 				// 字段名
                        var fieldName = fieldInfo instanceof Array ? fieldInfo[0] : fieldInfo.fieldName;
   		 				// 描述
                        var fieldNameDesc = fieldInfo instanceof Array ? fieldInfo[1] : fieldInfo.fieldNameDesc;
   		 				// 字段类型
   		 				var fieldType = fieldInfo instanceof Array ? null : fieldInfo.fieldType;
   		 				var fieldTypeName = fieldType == null ? "" : (fieldType.indexOf(".") < 0 ? fieldType : fieldType.substring(fieldType.lastIndexOf(".") + 1));
   		 				// 字段值
   		 				var allowValue = fieldInfo instanceof Array ? null : fieldInfo.allowValue;
   		 				// 输出
   		 				var hintField = underline(fieldName) + "#";
   		 				hintField += fieldType ? fieldTypeName + " " : "";
   		 				hintField += fieldNameDesc ? fieldNameDesc + " " : "";
   		 				hintField += (allowValue && !allowValue.startsWith("S")) ? allowValue.replace(/['\"]/g,"") : "";
   		 				hintField = hintField.trim();
   		 				fieldList.push(hintField);
   		 			}
   		 		}
   		 	}
   		 	var tableNameDesc = tableInfo.tableNameDesc;
   		 	var databaseDesc = tableInfo.databaseDesc;
   		 	if (tableNameDesc){
   		 		var tableDesc = databaseDesc ? "#表名# " + databaseDesc + " " + tableNameDesc : "#表名# " + tableNameDesc;
   		 		tables[" "][underline(tableName)] = tableDesc;
   		 	} else if (databaseDesc) {
   		 	    tables[" "][underline(tableName)] = "#表名# " + databaseDesc;
   		 	}
   		 	tables[underline(tableName)] = fieldList;
   		 }
   	 }
	return tables;
}


/**
 *  驼峰转下划线
 */
function underline(str){
	if (str == str.toUpperCase()){
        // 入参全大写则直接返回
        return str;
	}
	return str.replace(/\B([A-Z])/g, '_$1').toLowerCase()
}

/**
 * 初始化sql编辑器 CodeMirror 有 bug @see https://www.cnblogs.com/wenruo/p/8274958.html
 * hintOptions: {tables: {
 * users: ["name#名称", "score", "birthDate"],
 * countries: ["name", "population", "size"]
 * }}
 */
function initSqlEditor(tables) {

	$('.sql_textarea').each(function(index) {
        $this = $(this);
        if (!$this.data("editor")) {
            // 初始化编辑器
            window["sql_editor_"+index] = CodeMirror.fromTextArea(this, {
                mode: 'text/sysql', // sybn 自定义sql高亮
                indentWithTabs: true,
                smartIndent: true,
                lineNumbers: true,
                matchBrackets : true,
                lineWrapping: true, //是否自动换行
                autofocus: true,
                autoRefresh: true,
                viewportMargin: 100,
                extraKeys: {"Alt": "autocomplete"}, // 开启语法提示
                hintOptions: {tables:tables}
            });
            $this.data("editor", "sql_editor_"+index);
            $this.addClass("sql_textarea_refresh");
        } else {
            // 初始化代码提示
            var editor_id = $this.data("editor");
            var codeMirror = window[editor_id];
            codeMirror.options.hintOptions = {tables:tables};
            codeMirror.refresh();
            $this.addClass("sql_textarea_refresh");
            console.log(editor_id + "载入代码提示");
        }
	});
}

function sybnApiShowCreateTable(table) {
    var source = getQueryString("source");
    var dbsource = (source && url.indexOf("&dbsource=") < 0) ? source : "";
    if ($('.dbSource').val()) {
        dbsource = $('.dbSource').val();
    }
    var data = $.ajax({
        url : "api/sql/select_v2.json",
        type : 'post',
        timeout : 1000,
        data:{sql: "show create table `" + table + "`", dbsource:dbsource},
        async: false
    }).responseJSON;

    if (data && data.result && data.rows && data.rows.length == 1) {
        var res = data.rows[0]['Create Table'];
        console.log(res);
        return res;
    }
    return null;
}

function initSqlEditorByApi(url) {
    $(".show_table_prompt").text("[正在载入表结构...]");
    $(".show_table_prompt").closest(".panel").addClass("panel-warning").removeClass("panel-success");
    // 获取表结构
    $.ajax({
        type : "GET",
        url : url,
        dataType:"json",
        cache:true,
//        async:false,
        data : {database_name : getQueryString("database"),dbsource : getQueryString("dbsource", "")},
        success : function(data) {

            $(".show_table_prompt").text("[就绪]");
            $(".show_table_prompt").closest(".panel").removeClass("panel-warning").addClass("panel-success");

            // 将表结构转换为CodeMirror的格式
            var tables = getHintTableInfo(data);
            // 初始化sql编辑器
            initSqlEditor(tables);
            if ($(".sybn_treeview").length > 0) {
                /*
                dbs 数据格式:
                    "tableName" : "DwDataSource",
                    "database" : "biconfig",
                    "fieldList" : [ {
                          "fieldName" : "id",
                          "fieldNameDesc" : "id",
                     }
                 */
                var dbs = {};
                var dbDesc = {};
                for (var i in data.rows) {
                    var table = data.rows[i];
                    var database = table.database
                    dbDesc[database] = table.databaseDesc;
                    var tableName = table.tableName;
                    if (!dbs[database]) {
                        dbs[database]=[];
                    }
                    var nodes = [];
                    for (var j in table.fieldList) {
                        var field = table.fieldList[j];
                        var name = field instanceof Array ? field[0] : field.fieldName;
                        var desc = field instanceof Array ? field[1] : field.fieldNameDesc;
                        nodes.push({icon:'glyphicon_empty', text:html2Escape(name) + " <span class='silver'>" + html2Escape(desc) + "</span>", selectable:false});
                    }
                    var tableNode = {icon:'glyphicon glyphicon-list-alt', text:html2Escape(tableName) + " <span style='color:#999'>" + html2Escape(table.tableNameDesc) + "</span>", nodes:nodes, selectable:false, tags:[nodes.length]};
                    dbs[database].push(tableNode);
                }
                var dbNode = [];
                for (var db in dbs) {
                    dbNode.push({icon:'glyphicon glyphicon-home', text:html2Escape(db)+" <span style='color:#999'>库</span> <span style='color:#3c763d'>" + html2Escape((dbDesc[db]) ? dbDesc[db] : "") + "</span>", nodes:dbs[db], selectable:false, tags:[dbs[db].length]});
                }
                sybnSearchTableTree(dbNode);
            }
        }
    });
}

function copyText(text) {
    window.clipboardData.setData("Text",text);
}

$(document).ready(function() {
    $(document).on('click', '.sql_textarea_refresh', function (e) {
        $this = $(this);
        if ($this.data("editor")) {
            var editor_id = $this.data("editor");
            var codeMirror = window[editor_id];
            codeMirror.refresh();
            $this.removeClass("sql_textarea_refresh");
        }
    });
});

// @see https://www.bbsmax.com/A/RnJWKbPvJq/
function sybnSearchTableTree(defaultData) {
    var initSearchableTree = function(defaultData) {
        return $('#treeview-searchable').treeview({
            data: defaultData,
            nodeIcon: 'glyphicon glyphicon-globe',
            emptyIcon: '', //没有子节点的节点图标
            //collapsed: true,
            showTags:true
        });
    };
    var $searchableTree = initSearchableTree(defaultData);
    $('#treeview-searchable').treeview('collapseAll', {
        silent : false//设置初始化节点关闭
    });
    var findSearchableNodes = function() {
        return $searchableTree.treeview('search', [ $.trim($('#input-search').val()), { ignoreCase: false, exactMatch: false } ]);
    };
    var searchableNodes = findSearchableNodes();
    var search = function(e) {

        $searchableTree.treeview('clearSearch');
        $('#treeview-searchable').treeview('collapseAll', {
            silent : false//设置初始化节点关闭
        });

        var pattern = $.trim($('#input-search').val()).toLowerCase();

        if($.trim(pattern).length>0){
             var options = {
                      ignoreCase: true,
                      exactMatch: $('#chk-exact-match').is(':checked'),
                      revealResults: $('#chk-reveal-results').is(':checked')
            };
            var results = $searchableTree.treeview('search', [ pattern, options ]);

            var output = '<p>' + results.length + ' 匹配的搜索结果</p>';
            var $treeview = $.data($("#treeview-searchable")[0], 'treeview');
            $.each(results, function (index, result) {
                var parentHtml = "";
                if (result.parentId && $treeview.getParent(result.parentId)) {
                    parentHtml = '<span style="color:#369;">' + $treeview.getParent(result.parentId).text + '</span> ';
                }
                if (result.parentId && $treeview.getNode(result.parentId)) {
                    parentHtml += '<span style="color:gray;">' + $treeview.getNode(result.parentId).text + '</span> ';
                }
                output += '<p>- <span style="color:gray;">' + parentHtml + ' </span><span style="color:red;">' + result.text + '</span></p>';
            });

            $('#search-output').html(output);

            searchableNodes = findSearchableNodes();
        } else {
            $('#treeview-searchable').treeview('collapseAll', {
                silent : false  //设置初始化节点关闭
            });
            $('#search-output').text('');
        }
    }
    $('#btn-search').on('click', function (e) {
        if ($('#search-output').text() == '搜索中请稍等...') {
             $('#search-output').text('搜索中请稍等......');
             return;
        }
        $('#search-output').text('搜索中请稍等...');
        window.setTimeout(search, 500);
    });
    $('#btn-clear-search').on('click', function (e) {
        $searchableTree.treeview('clearSearch');
        $('#input-search').val('');
        $('#search-output').html('');
        $('#treeview-searchable').treeview('collapseAll', {
            silent : false//设置初始化节点关闭
        });
    });
}

function copyToClipboard(txt) {
   if (window.clipboardData) {
    window.clipboardData.clearData();
    clipboardData.setData("Text", txt);
    alert("复制成功！");

   } else if (navigator.userAgent.indexOf("Opera") != -1) {
    window.location = txt;
   } else if (window.netscape) {
    try {
     netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
    } catch (e) {
     alert("被浏览器拒绝！\n请在浏览器地址栏输入'about:config'并回车\n然后将 'signed.applets.codebase_principal_support'设置为'true'");
    }
    var clip = Components.classes['@mozilla.org/widget/clipboard;1'].createInstance(Components.interfaces.nsIClipboard);
    if (!clip)
     return;
    var trans = Components.classes['@mozilla.org/widget/transferable;1'].createInstance(Components.interfaces.nsITransferable);
    if (!trans)
     return;
    trans.addDataFlavor("text/unicode");
    var str = new Object();
    var len = new Object();
    var str = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
    var copytext = txt;
    str.data = copytext;
    trans.setTransferData("text/unicode", str, copytext.length * 2);
    var clipid = Components.interfaces.nsIClipboard;
    if (!clip)
     return false;
    clip.setData(trans, null, clipid.kGlobalClipboard);
    alert("复制成功！");
   }
}

